#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <vector>
#include"task.hpp"
#include<time.h>

using namespace std;

#define PROCESS_NUM 5

int waitCommand(int waitfd,bool& quit)
{
    uint32_t command = 0;
    ssize_t s = read(waitfd,&command,sizeof(command));

    if(s==0)
        quit = true;
    assert(s== sizeof(command));
    return command;
    
}
void sendAndWakeUp(const pair<pid_t,int>& s,uint32_t command)
{
    write(s.second,&command,sizeof(command));
    cout<< "main process: call process " << s.first << " execute " << desc[command] << " through" << s.second << endl;

}

int main()
{
    load();
    // pid:pidfd
    vector<pair<pid_t, int>> slots;
    for (int i = 0; i < PROCESS_NUM; i++)
    {
        // 创建管道
        int pipefd[2] = {0};
        int n = pipe(pipefd);
        assert(n != -1);
        (void)n;

        pid_t id = fork();
        assert(id != -1);
        if (id == 0)
        {
            // 子进程
            close(pipefd[1]);

            while(1)
            {
                bool quit = false;

                int command = waitCommand(pipefd[0],quit);
                
                if(quit)
                    break;
                
                if(command>=0 && command<handerSize())
                    callbacks[command]();
                else
                    cout<<"非法指令"<<command<<endl;
            }
            close(pipefd[0]);
            exit(1);
        }

        // 父进程
        close(pipefd[0]);
        slots.push_back(pair<pid_t,int>(getpid(),pipefd[1]));
    }
    srand((unsigned long)time(nullptr)^getpid()^131);

    while(true)
    {
        int command = rand()%handerSize();

        int choice = rand()%slots.size();

        sendAndWakeUp(slots[choice],command);
        sleep(1);
    }

    for(const auto& e:slots)
    {
        close(e.second);
    }

    for(const auto&e:slots)
    {
        waitpid(e.first,nullptr,0);
    }

    return 0;
}
